package com.lbj.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lbj.mall.common.constant.ProductAttrType;
import com.lbj.mall.common.utils.PageUtils;
import com.lbj.mall.common.utils.Query;
import com.lbj.mall.product.dao.AttrAttrgroupRelationDao;
import com.lbj.mall.product.dao.AttrDao;
import com.lbj.mall.product.dao.AttrGroupDao;
import com.lbj.mall.product.dao.CategoryDao;
import com.lbj.mall.product.entity.AttrAttrgroupRelationEntity;
import com.lbj.mall.product.entity.AttrEntity;
import com.lbj.mall.product.entity.AttrGroupEntity;
import com.lbj.mall.product.entity.CategoryEntity;
import com.lbj.mall.product.entity.vo.AttrGroupVo;
import com.lbj.mall.product.entity.vo.AttrIdAndAttrGroupIdVo;
import com.lbj.mall.product.entity.vo.AttrWithGroupVo;
import com.lbj.mall.product.service.AttrGroupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private AttrAttrgroupRelationDao relationDao;
    @Autowired
    private AttrDao attrDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catelogId) {
        IPage<AttrGroupEntity> page;
        IPage<AttrGroupEntity> iPage = new Query<AttrGroupEntity>().getPage(params);

        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        if (catelogId != 0) {
            // 判断 catelog_id 字段等于要查询的类别id
            wrapper.eq("catelog_id", catelogId);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and(item -> {
                item.eq("attr_group_id", key)
                        .or().like("attr_group_name", key);
            });
        }
        page = page(iPage, wrapper);

        return new PageUtils(page);
    }

    @Override
    public AttrGroupEntity getNewDataById(Long attrGroupId) {
        AttrGroupEntity attrGroup = baseMapper.selectById(attrGroupId);

        List<Long> catelogList = new ArrayList<>(3);
        List<Long> resultList = getCatelogPath(catelogList, attrGroup.getCatelogId());
        Collections.reverse(resultList);
        log.info("=======> " + resultList);
        attrGroup.setCatelogPath(resultList);
        return attrGroup;
    }

    @Override
    public List<Long> getCatelogPath(List<Long> catelogList, Long categoryId) {
        catelogList.add(categoryId);
        CategoryEntity category = categoryDao.selectById(categoryId);
        if (category.getParentCid() != null && category.getParentCid() != 0) {
            getCatelogPath(catelogList, category.getParentCid());
        }
        return catelogList;
    }

    /**
     * 根据属性分组ID获取所有属性信息
     */
    @Override
    public List<AttrEntity> getAttrFromRelation(Long attrGroupId) {
        // 属性分组id只存在于属性分组表和属性分组属性中间表中
        // 因为要查询属性，所以这里我们直接查询中间表，然后获得attrIds,再从属性表中获取数据
        List<AttrAttrgroupRelationEntity> entityList = relationDao.selectList(
                new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId)
        );
        // 查询所有相关联的中间表，获取所有对应的id，再从属性表中批量查询数据
        List<Long> idList = entityList.stream().map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        // 注意：这里的idList可能为空
        if (idList.size() == 0) return null;
        return attrDao.selectBatchIds(idList);
    }

    @Override
    public void deleteAttrRelation(List<AttrIdAndAttrGroupIdVo> list) {
        // 这里需要批量删除数据
        // 批量删除语句：创建多个SQL然后一条条执行；在一条SQL中执行删除
        // delete from pms_attr WHERE (条件1=？) or (条件2=？) or (条件3=？)

        // 因为要进入自定义的 AttrAttrgroupRelationDao 方法，所以这里需要转换实体类
        // 否则在 AttrAttrgroupRelationDao 中的泛型参数就会不一样，不规范
        List<AttrAttrgroupRelationEntity> relationEntityList = list.stream().map(item -> {
            AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item, entity);
            return entity;
        }).collect(Collectors.toList());
        relationDao.deleteBatchRelation(relationEntityList);
    }

    /**
     * 获取属性分组没有关联的其他属性（同一个类别下）
     */
    @Override
    public PageUtils getAttrGroupNoAttrList(Map<String, Object> params, Long attrGroupId) {
        // 1.根据属性分组id获取属性分组对应的类别id
        AttrGroupEntity attrGroupEntity = baseMapper.selectById(attrGroupId);
        // 获取类别id
        Long categoryId = attrGroupEntity.getCatelogId();

        // 2.根据类别id获取当前类别id下的所有属性
        List<AttrEntity> attrEntityList = attrDao.selectList(
                new QueryWrapper<AttrEntity>().eq("catelog_id", categoryId));
        // 只需要属性id
        List<Long> attrIdList = null;
        if (attrEntityList.size() != 0) {
            attrIdList = attrEntityList.stream().map(AttrEntity::getAttrId).collect(Collectors.toList());
        }

        // 3.查询当前分类id下所有被关联的属性
        List<AttrAttrgroupRelationEntity> relationList = null;
        if (attrIdList != null && attrIdList.size() != 0) {
            relationList = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .in("attr_id", attrIdList));
        }

        // 4.查出所有属性不包含第三步的所有属性
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
        if (relationList != null && relationList.size() != 0) {
            List<Long> collectIdList = relationList.stream().map(AttrAttrgroupRelationEntity::getAttrId)
                    .collect(Collectors.toList());
            wrapper.and(item -> item.notIn("attr_id", collectIdList));
        }

        // 5.模糊查询
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and(item -> {
                item.eq("attr_id", key).or().like("attr_name", key);
            });
        }

        // 6.还需要查询非销售属性
        wrapper.and(item -> item.eq("attr_type", ProductAttrType.BASE.getCode()));

        IPage<AttrEntity> page = attrDao.selectPage(new Query<AttrEntity>().getPage(params), wrapper);

        return new PageUtils(page);
    }

    @Override
    public List<AttrWithGroupVo> getAttrWithGroupByCategoryId(Long categoryId) {
        List<AttrGroupEntity> attrGroupList =
                list(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", categoryId));
        return attrGroupList.stream().map(item -> {
            AttrWithGroupVo vo = new AttrWithGroupVo();
            BeanUtils.copyProperties(item, vo);
            List<AttrEntity> attrs = getAttrFromRelation(item.getAttrGroupId());
            vo.setAttrs(attrs);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<AttrGroupVo> getAttrWithGroupByCategoryIdAndSpuId(Long catalogId, Long spuId) {
        return baseMapper.getAttrWithGroupByCategoryIdAndSpuId(catalogId,spuId);
    }
}